package nl.windgazer.arachne.services.facebook;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.Scanner;

import org.apache.log4j.Logger;
import org.apache.tapestry5.json.JSONArray;
import org.apache.tapestry5.json.JSONObject;
import org.apache.tapestry5.services.Context;

import nl.windgazer.arachne.services.ArachnePrivileges;

public class FacebookPrivileges implements ArachnePrivileges {

	private static Logger logger = Logger.getLogger(FacebookPrivileges.class);

	private static final String FILE_PATH = "/WEB-INF/facebookPrivileges.json";

	private FacebookOpenGraphDAO dao;
	private Context context;
	private JSONObject settings = null;

	public FacebookPrivileges (
			final FacebookOpenGraphDAO fbDAO
			, final Context context
	) {
		this.dao = fbDAO;
		this.context = context;
	}

	public String getPrivilegedID() {
		try {
			if (dao.getUser() != null) {
				return dao.getUser().getUID();
			}
		} catch (FacebookOpenGraphException e) {
		}
		
		return null;
	}

	public String[] getSecurityRoles() {
		try {
			if (dao.getUser() != null) {
				final JSONObject uj = getUserSettings(dao.getUser());
				final JSONArray rj = uj.getJSONArray("roles");
				String[] roles = new String[rj.length()];
				for (int i = 0; i < rj.length(); i++) {
					roles[i] = rj.getString(i);
				}
				return roles;
			}
		} catch (FacebookOpenGraphException e) {
		}
		return new String[0];
	}

	public boolean hasRole(String role) {
		try {
			return (dao.getUser() != null && Arrays.asList(getSecurityRoles()).contains(role));
		} catch (FacebookOpenGraphException e) {
			return false;
		}
	}

	
	private JSONObject getUserSettings(final FacebookUser u) {
		if (settings==null) {
			final File f = context.getRealFile(FILE_PATH);
			try {
				settings = new JSONObject(readFileAsString(f));
			} catch (FileNotFoundException e) {
				settings = createNewSettings();
				try {
					write(f, settings.toString());
				} catch (IOException e1) {
					logger.error("IO Exception while attempting to create new settings file for FacebookPrivileges!! " + f.getAbsolutePath());
				}
			}
		}
		final JSONArray users = settings.getJSONArray("users");
		for (int i = 0; i < users.length(); i++) {
			final JSONObject o = users.getJSONObject(i);
			if (u.getUID().equals(o.getString("uid"))) return o;
		}
		return createNewUserSettings(u);
	}

	private JSONObject createNewSettings() {
		final JSONObject settings = new JSONObject();
		settings.put("count", 0);
		settings.put("users", new JSONArray());
		return settings;
	}
	
	private JSONObject createNewUserSettings(final FacebookUser u) {
		final JSONObject o = new JSONObject("uid",u==null?"dummy":u.getUID());
		final JSONArray roles = new JSONArray();
		o.put("roles",roles);
		if (u==null) {
			roles.put("role1");
			roles.put("role2");
		}
		return o;
	}

	private String readFileAsString(File f) throws FileNotFoundException {

		StringBuilder text = new StringBuilder();
	    String NL = System.getProperty("line.separator");
	    Scanner scanner = new Scanner(new FileInputStream(f), "UTF-8");

	    try {
	      while (scanner.hasNextLine()){
	        text.append(scanner.nextLine() + NL);
	      }
	    }

	    finally{
	      scanner.close();
	    }

	    return text.toString();

	}

	void write(File f, String content) throws IOException  {

		Writer out = new OutputStreamWriter(new FileOutputStream(f), "UTF-8");

		try {
			out.write(content);
		}

		finally {
			out.close();
		}

	}

}
